﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MultiDAQ_Analysis.Calculation.Calculators;
using MultiDAQ_Analysis.Calculation.Interfaces;
using MultiDAQ_Analysis.Calculation.Parameters;
using MultiDAQ_Analysis.Calculation.Results;
using MultiDAQ_Analysis.Model;
using MultiDAQ_Analysis.Util;

namespace MultiDAQ_Analysis.Calculation.Calculators
{
    public class WorkingSourceEfficiencyCalculator : BaseMeasurementCalculator
    {
        public override string MeasurementType => "WorkingSourceEfficiency";
        public override Type ParameterType => typeof(WorkingSourceParameters);

        protected override async Task ProcessSingleRound(MeasurementCalculationContext context, MeasurementCalculationResult result)
        {
            // 工作源效率测量单轮处理：记录数据以便后续平均
            foreach (var kvp in context.RawData)
            {
                int channelIndex = kvp.Key;
                var (alpha, beta) = kvp.Value;

                result.ChannelResults[channelIndex] = new ChannelCalculationResult
                {
                    ChannelIndex = channelIndex,
                    AlphaResult = alpha,
                    BetaResult = beta,
                    //IsValid = alpha > 0 && beta > 0
                };
            }

            await Task.CompletedTask;
        }

        protected override async Task ProcessFinalCalculation(MeasurementCalculationContext context, MeasurementCalculationResult result)
        {
            var parameters = context.Parameters as WorkingSourceParameters;
            if (parameters == null)
                throw new ArgumentException("工作源效率测量参数类型错误");

            foreach (var channelHistory in context.HistoryData)
            {
                int channelIndex = channelHistory.Key;
                var measurements = channelHistory.Value;

                if (measurements.Count > 0)
                {
                    // 计算多轮测量的平均值
                    double alphaAvg = measurements.Average(m => m.alpha);
                    double betaAvg = measurements.Average(m => m.beta);
                    var (alphaBg, betaBg) = GetBackgroundData(channelIndex);

                    // 根据PDF公式计算工作源效率
                    // ηs(α) = [Rs(α) - Rb(α)] / I(α) × 100%
                    // ηs(β) = [Rs(β) - Rb(β)] / I(β) × 100%
                    double netAlphaRate = alphaAvg - alphaBg;
                    double netBetaRate = betaAvg - betaBg;

                    // 获取2π表面发射率参数
                    double alphaEmissionRate = parameters.AlphaEmissionRates.GetValueOrDefault(channelIndex, 1440);
                    double betaEmissionRate = parameters.BetaEmissionRates.GetValueOrDefault(channelIndex, 1594);

                    // 计算效率（保留百分比形式）
                    double alphaEfficiency = (netAlphaRate / alphaEmissionRate) * 100;
                    double betaEfficiency = (netBetaRate / betaEmissionRate) * 100;

                    // 计算效率比（α道比β道的比值）
                    double efficiencyRatio = betaAvg > 0 ? (alphaAvg / betaAvg) * 100 : 0;

                    // 计算串道比（根据PDF公式）
                    double crossTalkRatio = CalculateCrossTalkRatio(alphaAvg, betaAvg);

                    result.ChannelResults[channelIndex] = new ChannelCalculationResult
                    {
                        ChannelIndex = channelIndex,
                        AlphaResult = alphaEfficiency, // 工作源α效率 %
                        BetaResult = betaEfficiency,   // 工作源β效率 %
                        AlphaUncertainty = CalculateStandardDeviation(measurements.Select(m => m.alpha - alphaBg).ToList()),
                        BetaUncertainty = CalculateStandardDeviation(measurements.Select(m => m.beta - betaBg).ToList()),
                        //IsValid = ValidateWorkingSourceResults(netAlphaRate, netBetaRate, alphaEfficiency, betaEfficiency),
                        ExtendedResults = new Dictionary<string, double>
                        {
                            ["NetAlphaRate"] = netAlphaRate,
                            ["NetBetaRate"] = netBetaRate,
                            ["AlphaEmissionRate"] = alphaEmissionRate,
                            ["BetaEmissionRate"] = betaEmissionRate,
                            ["EfficiencyRatio"] = efficiencyRatio,
                            ["CrossTalkRatio"] = crossTalkRatio,
                            ["GeometryFactor"] = parameters.GeometryFactor
                        }
                    };

                    Console.WriteLine($"[工作源效率] 通道 {channelIndex + 1}: α效率={alphaEfficiency:F4}%, β效率={betaEfficiency:F4}%");
                }
            }

            await Task.CompletedTask;
        }

        protected override async Task SaveChannelResult(int channelIndex, ChannelCalculationResult channelResult, MeasurementCalculationResult overallResult)
        {
            var channelData = ChannelDataManager.LoadChannelData(channelIndex);

            // 将效率保存为小数形式（除以100）供其他测量使用
            channelData.WorkConditions.AlphaWorkEfficiency = channelResult.AlphaResult / 100.0;
            channelData.WorkConditions.BetaWorkEfficiency = channelResult.BetaResult / 100.0;
            channelData.LastModified = DateTime.Now;

            // 保存测量结果（保持百分比形式用于显示）
            if (channelData.MeasurementResults == null)
                channelData.MeasurementResults = new MeasurementResultData();

            channelData.MeasurementResults.WorkingSourceMeasurement = new WorkingSourceMeasurementResult
            {
                AlphaEfficiency = channelResult.AlphaResult,
                BetaEfficiency = channelResult.BetaResult,
                MeasurementTime = DateTime.Now,
                MeasurementDuration = overallResult.CalculationTime.Subtract(overallResult.CalculationTime).TotalMinutes
            };

            bool saveSuccess = ChannelDataManager.SaveChannelData(channelIndex, channelData);

            if (saveSuccess)
            {
                Console.WriteLine($"[保存] 通道 {channelIndex + 1} 工作源效率测量结果已保存");
            }
            else
            {
                Console.WriteLine($"[错误] 通道 {channelIndex + 1} 工作源效率测量结果保存失败");
            }

            await Task.CompletedTask;
        }

        /// <summary>
        /// 验证工作源测量结果的有效性
        /// </summary>
        private bool ValidateWorkingSourceResults(double netAlphaRate, double netBetaRate, double alphaEfficiency, double betaEfficiency)
        {
            // 净计数率必须为正
            if (netAlphaRate <= 0 || netBetaRate <= 0)
                return false;

            // 效率应在合理范围内（通常0.01% - 50%）
            if (alphaEfficiency < 0.01 || alphaEfficiency > 50 ||
                betaEfficiency < 0.01 || betaEfficiency > 50)
                return false;

            // β效率通常应大于α效率（对于大多数探测器）
            // 但这不是绝对要求，所以只作为警告
            if (alphaEfficiency > betaEfficiency * 2)
            {
                Console.WriteLine($"[警告] α效率({alphaEfficiency:F4}%)显著高于β效率({betaEfficiency:F4}%)，请检查参数设置");
            }

            return true;
        }

        /// <summary>
        /// 计算串道比（根据PDF中的公式）
        /// </summary>
        private double CalculateCrossTalkRatio(double alphaCount, double betaCount)
        {
            // 串道比 = α道的平均计数 / β道的平均计数 × 100%
            if (betaCount > 0)
            {
                return (alphaCount / betaCount) * 100;
            }
            return 0;
        }

        /// <summary>
        /// 获取工作源测量的质量控制信息
        /// </summary>
        public Dictionary<string, object> GetQualityControlInfo(MeasurementCalculationResult result)
        {
            var qcInfo = new Dictionary<string, object>();

            foreach (var channelResult in result.ChannelResults)
            {
                int channelIndex = channelResult.Key;
                var channelData = channelResult.Value;

                qcInfo[$"Channel_{channelIndex + 1}_AlphaEfficiency"] = channelData.AlphaResult;
                qcInfo[$"Channel_{channelIndex + 1}_BetaEfficiency"] = channelData.BetaResult;
                qcInfo[$"Channel_{channelIndex + 1}_EfficiencyRatio"] = channelData.ExtendedResults.GetValueOrDefault("EfficiencyRatio", 0);
                qcInfo[$"Channel_{channelIndex + 1}_CrossTalkRatio"] = channelData.ExtendedResults.GetValueOrDefault("CrossTalkRatio", 0);
                //qcInfo[$"Channel_{channelIndex + 1}_IsValid"] = channelData.IsValid;
            }

            return qcInfo;
        }
    }
}